using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;

public class UIManager : Singleton<UIManager>
{
    private Transform UIRoot;
    private Transform StaticUIRoot;
    private Transform DynamicUIRoot;

    private Dictionary<string, UIInfo> UIInfos;
    private List<UIInfo> OpenedUIList;
    private PathUtil PathUtil;

    // public UIManager()
    // {
    //     Init();
    // }
    public void Init()
    {
        PathUtil = new PathUtil();
        UIInfos = new Dictionary<string, UIInfo>();
        OpenedUIList = new List<UIInfo>();
        CreateRoot();
        LoadUIData();
        Debug.Log("[UIManager Init]");
    }

    private void LoadUIData()
    {
        string jsonData = Resources.Load<TextAsset>(PathUtil.GetUIDataPath()).text;
        UIInfos = JsonConvert.DeserializeObject<Dictionary<string, UIInfo>>(jsonData);
    }

    private void CreateRoot()
    {
        string UiRootPath = "UI/UIRoot";
        GameObject uiRootRes = Resources.Load<GameObject>(UiRootPath);
        if (uiRootRes == null)
        {
            Debug.LogError("未找到UIRoot资源");
        }
        UIRoot = GameObject.Instantiate(uiRootRes).transform;
        StaticUIRoot = UIRoot.transform.Find("StaticUIRoot");
        DynamicUIRoot = UIRoot.transform.Find("DynamicUIRoot");
        GameObject.DontDestroyOnLoad(UIRoot);
    }

    /// <summary>
    /// 打开指定UI面板
    /// </summary>
    /// <typeparam name="T">UI面板的类型</typeparam>
    /// <returns>对应的UI面板实例</returns>
    public UIBasePanel Open<T>(object opd = null)
    {
        string uiName = typeof(T).Name;
        return Open(uiName, opd);
    }

    public UIBasePanel Open(string uiName, object opd = null)
    {
        if (UIInfos.ContainsKey(uiName))
        {
            UIInfo uiInfo = UIInfos[uiName];
            UIBasePanel panelInstance = uiInfo.PanelInstance;
            if (uiInfo.IsOpen)
            {
                Debug.LogWarning($"{uiName}面板已经打开,将不会再次调用OnOpen方法");
            }
            else
            {
                if (panelInstance == null)
                {
                    #region 实例化新的UI
                    GameObject uiRes = Resources.Load<GameObject>(PathUtil.GetUIPath(uiName));
                    if (uiRes == null)
                    {
                        Debug.LogError($"未找到对应路径下的UI资源:");
                        return null;
                    }
                    panelInstance =
                        GameObject.Instantiate(uiRes).AddComponent(Type.GetType(uiName))
                        as UIBasePanel;
                    Transform targetTrans = null;
                    if (uiInfo.IsDynamic)
                    {
                        targetTrans = DynamicUIRoot.transform.Find(uiInfo.Layer.ToString());
                    }
                    else
                    {
                        targetTrans = StaticUIRoot.transform.Find(uiInfo.Layer.ToString());
                    }
                    if (targetTrans == null)
                    {
                        targetTrans = StaticUIRoot;
                        Debug.LogWarning("未找到UI对应的层级，请检查UIRoot每一个Canvas下是否包含所有UILayer的名称");
                    }
                    panelInstance.transform.SetParent(targetTrans, false);

                    panelInstance.OnInit(uiInfo);
                    UIInfos[uiName].PanelInstance = panelInstance;
                    #endregion
                }
                panelInstance.OnOpen();
                panelInstance.transform.SetAsLastSibling();
                uiInfo.IsOpen = true;
                uiInfo.opd = opd;
                OnUIOpen(uiInfo);

            }
            return panelInstance;
        }
        else
        {
            Debug.LogError($"开启面板失败，{uiName}面板不存在");
            return null;
        }
    }

    /// <summary>
    /// 关闭指定UI面板
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public void Close<T>()
        where T : UIBasePanel
    {
        string uiName = typeof(T).Name;
        Close(uiName);
    }

    public void Close(string uiName)
    {
        if (UIInfos.ContainsKey(uiName))
        {
            UIInfo uiInfo = UIInfos[uiName];
            if (uiInfo.IsOpen)
            {
                uiInfo.PanelInstance.OnClose();
                uiInfo.IsOpen = false;
                OnUIClose(uiInfo);
            }
            else
            {
                Debug.LogWarning($"关闭面板失败，{uiName}面板未开启");
            }
        }
        else
        {
            Debug.LogError($"关闭面板失败，{uiName}面板不存在");
        }
    }

    /// <summary>
    /// 关闭最近打开的面板
    /// </summary>
    public bool CloseRecent()
    {
        int index = OpenedUIList.Count - 1;
        while (index >= 0 && OpenedUIList[index].ControlMode == UIControlMode.System)
        {
            index--;
        }
        if (index >= 0)
        {
            Close(OpenedUIList[index].UIName);
            return true;
        }
        return false;
    }

    public void CloseAll()
    {
        int count = OpenedUIList.Count;

        for (int i = count - 1; i >= 0; i--)
        {
            Close(OpenedUIList[i].UIName);
        }
    }

    /// <summary>
    /// 获取指定面板的实例
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public UIBasePanel GetPanel<T>()
        where T : UIBasePanel
    {
        string uiName = typeof(T).Name;
        return GetPanel(uiName);
    }

    public UIBasePanel GetPanel(string uiName)
    {
        if (UIInfos.ContainsKey(uiName))
        {
            return UIInfos[uiName].PanelInstance;
        }
        else
        {
            Debug.LogError($"获取Panel失败：{uiName}不存在");
            return null;
        }
    }

    private void OnUIOpen(UIInfo uiInfo)
    {
        OpenedUIList.Add(uiInfo);
        if (uiInfo.OverlayMode == UIOverlayMode.NewPanel)
        {
            //如果当前面板不是叠加的，先调用上一个非叠加面板的关闭
            int lastPanelIndex = OpenedUIList.Count - 2;
            while (
                lastPanelIndex >= 0
                && OpenedUIList[lastPanelIndex].OverlayMode != UIOverlayMode.NewPanel
            )
            {
                --lastPanelIndex;
            }
            if (lastPanelIndex >= 0)
            {
                OpenedUIList[lastPanelIndex].PanelInstance.HideUI();
            }
        }
    }

    private void OnUIClose(UIInfo uiInfo)
    {
        if (uiInfo.OverlayMode == UIOverlayMode.NewPanel)
        {
            int index = OpenedUIList.IndexOf(uiInfo);
            if (index == OpenedUIList.Count - 1)
            {
                int lastPanelIndex = OpenedUIList.Count - 2;
                while (
                    lastPanelIndex >= 0
                    && OpenedUIList[lastPanelIndex].OverlayMode != UIOverlayMode.NewPanel
                )
                {
                    --lastPanelIndex;
                }
                if (lastPanelIndex >= 0)
                {
                    OpenedUIList[lastPanelIndex].PanelInstance.ShowUI();
                }
            }
        }
        OpenedUIList.Remove(uiInfo);
    }
}

public class UIInfo
{
    public string UIName;
    public bool IsCache;
    public bool IsDynamic; //是否是动态UI，例如屏幕外导航
    public UIOverlayMode OverlayMode;
    public UIControlMode ControlMode;
    public UILayer Layer;

    public UIBasePanel PanelInstance;
    public bool IsOpen = false;

    public object opd = null;
}

public enum UILayer
{
    Back,
    Mid,
    Front
}

public enum UIOverlayMode
{
    NewPanel, //独立的UI界面，同时只能显示一个,例如活动页面，点击活动后跳转的页面
    Additive //叠加模式，例如弹窗
}

public enum UIControlMode
{
    System, //完全由代码控制UI的开关，例如物品不足提示UI
    Player //玩家可以主动开启或关闭，点击按钮或者使用快捷键开关
}

public class PathUtil
{
    public static string GetUIPath(string uiName)
    {
        return $"UI/{uiName}";
    }

    public static string GetUIDataPath()
    {
        return "Data/Json/UIInfos";
    }
}

public class UIData<T>
{
    public T Data;
}

